local class = require('middleclass')
local utils = require('utils')
local raylib = require('raylib')
local Object = class('Object')

function Object:initialize(x, y, w, h, parent)
    self.x = 0
    self.y = 0
    self.w = 0
    self.h = 0
    self.uid = utils.uuid()
    self.z_index = 0
    self.parent = nil
    self.children = {}
    self.color = raylib.Color(255, 255, 255, 255)
    self._dirty = false

    self:place(x, y)
    self:resize(w, h)
    self:set_parent(parent)
end

function Object:place(x, y)
    if type(x) == 'number' then
        self.x = x
        self._dirty = true
    end
    if type(y) == 'number' then
        self.y = y
        self._dirty = true
    end
end

function Object:resize(w, h)
    if type(w) == 'number' and w >= 0 then
        self.w = w
        self._dirty = true
    end
    if type(h) == 'number' and h >= 0 then
        self.h = h
        self._dirty = true
    end
end

function Object:set_parent(parent)
    if parent == nil and self.parent ~= nil then
        self._dirty = true
        self.parent = nil
        return
    end
    if
        self.parent ~= parent and type(parent) == 'table' and parent.isInstanceOf and
            (parent:isInstanceOf(Gui.Object) or parent:isInstanceOf(Gui.Canvas))
     then
        self.parent = parent
        self._dirty = true
    end
end

function Object:add(object)
    if
        type(object) == 'table' and object.isInstanceOf and object:isInstanceOf(Gui.Object) and
            not self:find_child(object)
     then
        self.children[#self.children + 1] = object
    end
end

function Object:find_child(object)
    if type(object) == 'table' and object.isInstanceOf and object:isInstanceOf(Gui.Object) then
        for i, v in ipairs(self.children) do
            if v == object then
                return i
            end
        end
    end
    return nil
end

function Object:can_draw()
    return not self.parent or not self._dirty
end

function Object:debug_draw()
    if not self:can_draw() then
        return
    end
end

function Object:draw()
    if not self:can_draw() then
        return
    end
end

return Object
